home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1998 January / EnigmA AMIGA RUN 24 (1997)(G.R. Edizioni)(IT)[!][issue 1998-01 & 02].iso / LISTATI / main.c < prev    next >
C/C++ Source or Header  |  1997-11-11  |  10KB  |  270 lines

  1. //**********************************************************************
  2. //*                                                                    *
  3. //*      Algoritmo per la decodifica di immagini IFF-ILBM              *
  4. //*                                                                    *
  5. //**********************************************************************
  6.  
  7.  
  8. #include <exec/memory.h>
  9. #include <exec/types.h>
  10. #include <graphics/gfxbase.h>
  11. #include <intuition/intuition.h>
  12. #include <stdio.h>
  13.  
  14. #include <clib/exec_protos.h>
  15. #include <clib/graphics_protos.h>
  16. #include <clib/intuition_protos.h>
  17.  
  18. #define LIB_VERSION      39
  19. #define DIM_MSG          20
  20. #define NUM_MSG          10
  21. #define DIM_RICERCA      2000
  22. #define PUB_PULITA       MEMF_PUBLIC|MEMF_CLEAR
  23.  
  24. #define ERR_MEMORIA      1
  25. #define ERR_LIBS         2
  26. #define ERR_TIPO_FILE    3
  27.  
  28. #define ID_IFF_FORM 0x464F524D   //id header IFF (parola "FORM")
  29. #define ID_IFF_ILBM 0x494C424D   //id iff (parola "ILBM")
  30. #define ID_IFF_BMHD 0x424D4844   //id IFF (parola "BMHD")
  31. #define ID_IFF_CMAP 0x434D4150   //id iff (parola "CMAP")
  32. #define ID_IFF_CAMG 0x43414D47   //id IFF (parola "CAMG")
  33. #define ID_IFF_BODY 0x424F4459   //id iff (parola "BODY")
  34.  
  35.  
  36. struct chunk {
  37.        ULONG id;
  38.        ULONG dimens;
  39.        UBYTE *buffer;
  40.   };// CMAP CAMG e BODY hanno praticamente la stessa struttura
  41.  
  42. struct chunk_bmhd {
  43.    ULONG id;
  44.        ULONG dimens;
  45.        UWORD lx_immagine;
  46.        UWORD ly_immagine;
  47.        UWORD x_bitmap;
  48.        UWORD y_bitmap;
  49.        UBYTE piani;
  50.        UBYTE decodifica;
  51.        UBYTE compressione;
  52.        UWORD colore_trasparente;
  53.        UBYTE x_aspetto_pixel;
  54.        UBYTE y_aspetto_pixel;
  55.        UWORD lx_schermo;
  56.        UWORD ly_schermo;
  57.   };
  58.  
  59. struct Library     *intuibase=NULL,
  60.                    *gfxbase=NULL;
  61. struct chunk       *cmap=NULL,
  62.                    *camg=NULL,
  63.                    *body=NULL;
  64. struct chunk_bmhd  bmhd; //BMHD ha grandezza fissa
  65.  
  66.  
  67. //  ##########  dichiarazioni delle funzioni C usate  #################
  68.  
  69. void   Dealloca_Buffers();
  70. ULONG  Find_Id (ULONG,UBYTE*,ULONG);
  71. struct chunk* File_To_Buffer(FILE*,ULONG,UBYTE*,ULONG);
  72. int    DecodeIff(FILE*);
  73. void   CloseLibs();
  74.  
  75. //  ##########  inizio listato  ######################################
  76.  
  77. int main (int argc,char **argv)
  78. {
  79.   FILE* finput = NULL;
  80.   int numero_files=1;
  81.   if ((intuibase=(struct Library*)OpenLibrary("intuition.library",LIB_VERSION))==NULL) return (ERR_LIBS);
  82.   // La funzione OpenLibrary apre una libreria di sistema.
  83.   // Accetta come argomenti il nome della libreria da aprire (UBYTE*) e la versione
  84.   // della stessa (ULONG).
  85.   // in caso di riuscita apertura della lireria restituisce l'indirizzo
  86.   // della struttura libreria appena allocata,viceversa 0 (NULL).
  87.   if ((gfxbase  =(struct Library*)OpenLibrary("graphics.library",LIB_VERSION))==NULL)
  88.   {
  89.      CloseLibrary(intuibase);
  90.      return (ERR_LIBS);
  91.   }
  92.   for (numero_files=1;numero_files < argc;numero_files++)
  93.      if ((finput = fopen(argv[numero_files],"r")))
  94.      {
  95.        rewind ( finput );
  96.        DecodeIff ( finput );
  97.        fclose ( finput );
  98.      }
  99.   if (intuibase) CloseLibrary (intuibase);
  100.   if (gfxbase)   CloseLibrary (gfxbase);
  101.   return(0);
  102. }
  103.  
  104. void Dealloca_Buffers()
  105.  // Questa funzione dealloca i buffer puntati dalle nostre varibili globali,
  106.  // e successivamente dealloca le strutture chunk.
  107. {
  108.   if (cmap->buffer) FreeMem(cmap->buffer,cmap->dimens);
  109.   if (camg->buffer) FreeMem(camg->buffer,camg->dimens);
  110.   if (body->buffer) FreeMem(body->buffer,body->dimens);
  111.   if (cmap)         FreeMem(cmap,sizeof(struct chunk));
  112.   if (camg)         FreeMem(camg,sizeof(struct chunk));
  113.   if (body)         FreeMem(body,sizeof(struct chunk));
  114.   cmap=NULL;camg=NULL;body=NULL;
  115. }
  116.  
  117. ULONG Find_Id(ULONG id, UBYTE* buffer,ULONG dimens_buffer)
  118.   // Questa funzione permette di cercare l'header in un buffer in memoria.
  119.   // "carattere" contiene la prima "lettera" che compone l'ID.
  120.   // Il resto del codice è una normale ricerca sequenziale.
  121.   // La funzione ritorna la posizione del chunk nel buffer (e quindi nel
  122.   // file) in caso di successo e il valore -1 in caso di insuccesso.
  123. {
  124.   ULONG  posiz=0;
  125.   UBYTE  trovato=0;
  126.   UBYTE  carattere=UBYTE(id>>24);
  127.   ULONG* indice=(ULONG*)buffer;
  128.   while ((posiz < dimens_buffer) & (!trovato))
  129.   {
  130.     if (carattere == (*indice>>24)) if (*indice == id) trovato=1;
  131.     ((UBYTE*)indice)++;
  132.     if (!trovato) posiz++;
  133.   }
  134.   if (trovato) return(posiz);
  135.   return(-1);
  136. }
  137.  
  138. struct chunk* File_To_Buffer(FILE *finput,ULONG id,UBYTE* buffer,ULONG dimens)
  139.  
  140.  // Questa funzione crea il chunk vero e proprio trasferendo i dati dal
  141.  // file in memoria. La funzione ritorna il PUNTATORE alla struttura
  142.  // chunk in caso di successo, 0 (NULL) altrimenti.
  143. {
  144.   struct chunk *appo=NULL;
  145.   ULONG  posizione_id=0;
  146.   if ((appo=AllocMem(sizeof(struct chunk),MEMF_PUBLIC))==NULL) return(0);
  147.   posizione_id = Find_Id(id,buffer,dimens);
  148.   if (posizione_id == (-1)) goto errore_fatale;
  149.   fseek(finput,posizione_id,SEEK_SET);
  150.   fread((char*)&appo->id,1,4,finput);
  151.   fread((char*)&appo->dimens,1,4,finput);
  152.   if ((appo->buffer=AllocMem(appo->dimens,MEMF_PUBLIC))==NULL) goto errore_fatale;
  153.   fread((char*)appo->buffer,1,appo->dimens,finput);
  154.   return(appo);
  155.   errore_fatale: // La memoria è finita! Andate in pace.
  156.   FreeMem(appo,sizeof(struct chunk));
  157.   return(0);
  158. }
  159.  
  160. int DecodeIff(FILE* finput)
  161. {
  162.   struct Screen     *schermo=NULL;
  163.   struct Window     *finestra1=NULL,
  164.                     *finestra2=NULL;
  165.   struct BitMap     immagine;
  166.   ULONG   i=0,j=0,r=0,g=0,b=0,riga=0;
  167.   UBYTE   cicli=0,numero_bytes=0,bytes_per_riga=0,num_piano=0;
  168.   UBYTE*  buffer=NULL;
  169.   UBYTE*  appo=NULL;
  170.   UBYTE*  indirizzo=NULL;
  171.   ULONG   general=0;
  172.   ULONG   dimens_buffer=DIM_RICERCA;
  173.   ULONG*  camg_data=NULL;
  174.  
  175.   fread ((char*)&general,1,4,finput);
  176.   if (general != ID_IFF_FORM) return(-2);
  177.   fread ((char*)&general,1,4,finput);
  178.   if (general<dimens_buffer) dimens_buffer=general-4;
  179.   if ((buffer=AllocMem(dimens_buffer,MEMF_PUBLIC))==NULL) return(-3);
  180.   fread ((char*)&general,1,4,finput);
  181.   if (general != ID_IFF_ILBM) return(-4);
  182.   rewind (finput);
  183.   fread (buffer,1,dimens_buffer,finput);
  184.   
  185.   general=Find_Id(ID_IFF_BMHD,buffer,dimens_buffer);
  186.   if (general == -1 )
  187.    { FreeMem(buffer,dimens_buffer);
  188.      return(ERR_TIPO_FILE);
  189.    }
  190.   fseek(finput,general,SEEK_SET);
  191.   fread((char *)&bmhd,1,sizeof(struct chunk_bmhd),finput);
  192.   cmap=File_To_Buffer(finput,ID_IFF_CMAP,buffer,dimens_buffer);
  193.   camg=File_To_Buffer(finput,ID_IFF_CAMG,buffer,dimens_buffer);
  194.   body=File_To_Buffer(finput,ID_IFF_BODY,buffer,dimens_buffer);
  195.   if ((cmap)&&(body)&&(camg))
  196.   { if (bmhd.decodifica==1)   goto errore_2;
  197.     if (bmhd.compressione>1)  goto errore_2;
  198.     while((bmhd.lx_immagine % 16)) bmhd.lx_immagine++;
  199.     InitBitMap(&immagine,bmhd.piani,bmhd.lx_immagine,bmhd.ly_immagine);
  200.     for (i=0; i<bmhd.piani; i++)
  201.        if ((immagine.Planes[i]=AllocRaster(bmhd.lx_immagine,bmhd.ly_immagine))==NULL)
  202.         { for (j=0;j<i;j++) FreeRaster(immagine.Planes[j],bmhd.lx_immagine,bmhd.ly_immagine);
  203.           goto errore_2;
  204.         }
  205.     camg_data=(ULONG*)camg->buffer;
  206.     if ((schermo=(struct Screen*)OpenScreenTags(NULL,
  207.     SA_Width,bmhd.lx_schermo,    SA_Height,bmhd.ly_schermo,
  208.     SA_DisplayID,*camg_data,     SA_Depth,bmhd.piani,
  209.     SA_FullPalette,TRUE,         SA_Title,"IFF Reader V 1.0",
  210.     TAG_END,NULL))==NULL) goto errore_3;
  211.  
  212.   appo=cmap->buffer;
  213.   for(i=0;i<(cmap->dimens/3);i++)
  214.   {
  215.     r=ULONG(*(appo++));
  216.     g=ULONG(*(appo++));
  217.     b=ULONG(*(appo++));
  218.     r+=r<<8;r+=r<<16;
  219.     g+=g<<8;g+=g<<16;
  220.     b+=b<<8;b+=b<<16;
  221.     SetRGB32(&schermo->ViewPort,i,r,g,b);
  222.   }
  223.     bytes_per_riga=bmhd.lx_immagine/8;
  224.     appo=body->buffer;
  225.     for (riga=0;riga<bmhd.ly_immagine;riga++)
  226.     { for(num_piano=0;num_piano<bmhd.piani;num_piano++)
  227.        { indirizzo=immagine.Planes[num_piano]+bytes_per_riga*riga;
  228.            if (bmhd.compressione==1)
  229.            { numero_bytes=0;
  230.              while (numero_bytes<bytes_per_riga)
  231.              { cicli=UBYTE(*(appo++));
  232.                if ((cicli)>127)
  233.                { cicli=(-cicli)+1;
  234.                  for(i=0;i<cicli;i++,numero_bytes++,indirizzo++) *indirizzo=*appo;
  235.                  appo++;
  236.                }
  237.                else for(i=0;i<=cicli;i++,numero_bytes++) *(indirizzo++)=*(appo++);
  238.              }
  239.            }
  240.            else for(i=0;i<bytes_per_riga;i++) *(indirizzo++)=*(appo++);
  241.        }
  242.     }
  243.   if ((finestra2=(struct Window*)OpenWindowTags(NULL,
  244.   WA_Left ,0,                  WA_Top,0,
  245.   WA_Width,bmhd.lx_immagine,   WA_Height,bmhd.ly_immagine,
  246.   WA_SmartRefresh,TRUE,        WA_CustomScreen,schermo,
  247.   WA_Borderless,TRUE,          WA_Title,"IFF Output",
  248.   WA_SuperBitMap,&immagine,    TAG_END,NULL))==NULL) goto errore_3;
  249.   if ((finestra1=(struct Window*)OpenWindowTags(NULL,
  250.   WA_Left,0,                   WA_Top,0,
  251.   WA_Width,120,                WA_Height,15,
  252.   WA_DetailPen,1,              WA_BlockPen,0,
  253.   WA_IDCMP,IDCMP_CLOSEWINDOW,  WA_CustomScreen,schermo,
  254.   WA_CloseGadget,TRUE,         WA_DragBar,TRUE,
  255.   WA_Title,"<- Click ",        TAG_END,NULL))==NULL) goto errore_3;
  256.   if(finestra1)Wait(1L << finestra1->UserPort->mp_SigBit);
  257.   }
  258. errore_3:
  259.   if (finestra2) CloseWindow (finestra2);// Prima si chiudono sempre le
  260.   if (finestra1) CloseWindow (finestra1);// finestre poi lo schermo, altrimenti
  261.   if (schermo)   CloseScreen (schermo);  // si GURA!
  262.   for (i=0;i<bmhd.piani;i++)// Liberiamo i bitplanes
  263.       FreeRaster (immagine.Planes[i],bmhd.lx_immagine,bmhd.ly_immagine);
  264. errore_2:
  265.   Dealloca_Buffers();
  266. errore_1:
  267.   if (buffer) FreeMem(buffer,dimens_buffer);
  268.   return(0);
  269. }
  270.